﻿
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Net.Http.Formatting;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Security;
using System.Threading;
using IPBoss.Copyright.Entities;
using IPBoss.Copyright.Entities.ViewModel;
using System.Web;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using IPBoss.Copyright.Entities.WebSiteModel;
using System.Linq;

namespace IPBoss.Copyright.UtilityHelper
{
    public static class HttpHelper
    {

        public static string Post(string url, string paramData)
        {
            return Post(url, paramData, Encoding.UTF8);
        }

        public static string Post(string url, string paramData, Encoding encoding)
        {
            string result = "";

            if (url.ToLower().IndexOf("https", System.StringComparison.Ordinal) > -1)
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((sender, certificate, chain, errors) => { return true; });
            }
            var wc = new WebClient();
            try
            {

                if (string.IsNullOrEmpty(wc.Headers["Content-Type"]))
                {
                    wc.Headers.Add("Content-Type", "application/json");
                }
                wc.Encoding = encoding;
                result = wc.UploadString(url, "POST", paramData);
            }
            catch (Exception e)
            {
                Log4NetHelper.Error("Post", url, e);//重试3次
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        Thread.Sleep(10000);
                        result = wc.UploadString(url, "POST", paramData);
                        break;
                    }
                    catch (Exception ex)
                    {
                        Log4NetHelper.Error("Post", paramData, ex);
                        continue;
                    }
                }
                if (result == "")
                    throw e;
            }

            return result;
        }
        public static T LoadDataWithPostBusinessPlat<T, M>(string restAction, M postData)
        {

            try
            {
                using (HttpClient client = CreateHttpClientBusinessPlat())
                {
                    Task<HttpResponseMessage> task = client.PostAsJsonAsync(restAction, postData);
                    task.Wait();
                    if (!task.Result.IsSuccessStatusCode)
                    {
                        Task<string> contentTask = task.Result.Content.ReadAsStringAsync();
                        contentTask.Wait();
                        
                    }
                    else
                    {
                        Task<T> dataTask = task.Result.Content.ReadAsAsync<T>();
                        dataTask.Wait();
                        T data = dataTask.Result;
                        return data;
                    }
                }
            }
            catch (Exception ex)
            {
               
                throw ex;
            }

           
            throw new Exception("Error.");
        }

        private static HttpClient CreateHttpClientBusinessPlat()
        {
           
            string url = Static.SystemConfigs != null && Static.SystemConfigs.Where(k => k.KeyName == "PlatHost").Count() > 0 ? Static.SystemConfigs.Where(k => k.KeyName == "PlatHost").FirstOrDefault()?.Value : ConfigHelper.GetAppSetting("PlatHost") + "/";
            HttpClientHandler handler = new HttpClientHandler();
            handler.MaxRequestContentBufferSize = ConfigHelper.GetAppSettingInt("MaxResponseContentBufferSize", int.MaxValue);
            HttpClient client = new HttpClient(handler); 
            client.BaseAddress = new Uri(url);
            client.MaxResponseContentBufferSize = ConfigHelper.GetAppSettingInt("MaxResponseContentBufferSize", int.MaxValue);
            client.Timeout = new TimeSpan(0, 0, 180);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            return client;
        }

        public static T Get<T>(string url)
        {
            try
            {
                var wc = new WebClient { Encoding = Encoding.UTF8 };
                var readStream = wc.OpenRead(url);
                using (var sr = new StreamReader(readStream, Encoding.UTF8))
                {
                    var result = sr.ReadToEnd();
                    T data = JsonConvert.DeserializeObject<T>(result);
                    return data;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 发起GET同步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string HttpGet(string url, string contentType = null, Dictionary<string, string> headers = null)
        {
            using (HttpClient client = new HttpClient())
            {
                if (contentType != null)
                    client.DefaultRequestHeaders.Add("ContentType", contentType);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                HttpResponseMessage response = client.GetAsync(url).Result;
                return response.Content.ReadAsStringAsync().Result;
            }
        }

        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static async Task<string> HttpGetAsync(string url, string contentType = null, Dictionary<string, string> headers = null)
        {
            using (HttpClient client = new HttpClient())
            {
                if (contentType != null)
                    client.DefaultRequestHeaders.Add("ContentType", contentType);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                HttpResponseMessage response = await client.GetAsync(url);
                return await response.Content.ReadAsStringAsync();
            }
        }
        /// <summary>
        /// 获得13位的时间戳
        /// </summary>
        /// <returns></returns>
        public static string GetTimeStamp()
        {
            System.DateTime time = System.DateTime.Now;
            long ts = ConvertDateTimeToInt(time);
            return ts.ToString();
        }
        /// <summary>  
        /// 将c# DateTime时间格式转换为Unix时间戳格式  
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns>long</returns>  
        private static long ConvertDateTimeToInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }
        /// <summary>        
        /// 时间戳转为C#格式时间        
        /// </summary>        
        /// <param name=”timeStamp”></param>        
        /// <returns></returns>        
        public static DateTime ConverLongToDateTime(long timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }
        public static T PostCopyright<T>(string url, WebUserInfo webUserInfo,string referer=null)
        {
            try
            {
                HttpWebRequest httpRequset = (HttpWebRequest)WebRequest.Create(url);
                CookieContainer myCookieContainer = new CookieContainer();
                httpRequset.CookieContainer = myCookieContainer;
                httpRequset.Method = "GET";
                httpRequset.Accept = "application/json, text/plain, */*";
                httpRequset.Host = ConfigHelper.GetAppSetting("Host");
                httpRequset.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN,zh;q=0.9");
                httpRequset.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + webUserInfo.authorization_token);
                httpRequset.Headers.Add("authorization_key", webUserInfo.authorization_key);
                httpRequset.Headers.Add("device", "pc");
                httpRequset.Headers.Add("authorization_token", webUserInfo.authorization_token);
                httpRequset.UserAgent = ConfigHelper.GetAppSetting("UserAgent");
                if (referer != null)
                    httpRequset.Referer = referer;
                httpRequset.KeepAlive = true;
                HttpWebResponse response = (HttpWebResponse)httpRequset.GetResponse();//获得 服务端响应

                //带压缩的解码
                Encoding encode = System.Text.Encoding.GetEncoding("UTF-8");
                Stream responseStream = null;
                if (response.ContentEncoding.ToLower() == "gzip")
                {
                    responseStream = new System.IO.Compression.GZipStream(response.GetResponseStream(), System.IO.Compression.CompressionMode.Decompress);
                }
                else if (response.ContentEncoding.ToLower() == "deflate")
                {
                    responseStream = new System.IO.Compression.DeflateStream(response.GetResponseStream(), System.IO.Compression.CompressionMode.Decompress);
                }
                else
                {
                    responseStream = response.GetResponseStream();
                }
                StreamReader sr = new StreamReader(responseStream, encode);
                Static.Cookies = myCookieContainer;
                string content = sr.ReadToEnd();
                httpRequset.Abort();
                return JsonHelper.Deserialize<T>(content);
            }
            catch(Exception ex) {
                Log4NetHelper.Error("PostCopyright", url, ex);
                return default(T);
            }

        }



        /// <summary>
        /// 上传执行 方法
        /// </summary>
        /// <param name="parameter">上传文件请求参数</param>
        public static string ExecuteUpload(HttpParameterType parameter)
        {
            string strcookie = "";
            string strkey = "";
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
            using (MemoryStream memoryStream = new MemoryStream())
            {

                if (Static.CcCookies.Count > 0)
                {
                    string[] cookieresult = Static.CcCookies[0].Value.ToString().Split('"');
                    strcookie = cookieresult[3];
                    strkey = cookieresult[7];
                }
                else
                {
                    return "未登录";
                }


                // 1.分界线
                string boundary = string.Format("----{0}", DateTime.Now.Ticks.ToString("x")),       // 分界线可以自定义参数
                    beginBoundary = string.Format("--{0}\r\n", boundary),
                    endBoundary = string.Format("\r\n--{0}--\r\n", boundary);
                byte[] beginBoundaryBytes = parameter.Encoding.GetBytes(beginBoundary),
                    endBoundaryBytes = parameter.Encoding.GetBytes(endBoundary);
                // 2.组装开始分界线数据体 到内存流中
                memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);
                // 3.组装 上传文件附加携带的参数 到内存流中
                if (parameter.PostParameters != null && parameter.PostParameters.Count > 0)
                {
                    foreach (KeyValuePair<string, string> keyValuePair in parameter.PostParameters)
                    {
                        string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n{2}", keyValuePair.Key, keyValuePair.Value, beginBoundary);
                        byte[] parameterHeaderBytes = parameter.Encoding.GetBytes(parameterHeaderTemplate);

                        memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length);
                    }
                }
                // 4.组装文件头数据体 到内存流中
                string fileHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n", parameter.FileNameKey, parameter.FileNameValue);
                byte[] fileHeaderBytes = parameter.Encoding.GetBytes(fileHeaderTemplate);
                memoryStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
                // 5.组装文件流 到内存流中
                byte[] buffer = new byte[1024 * 1024 * 1];
                int size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                while (size > 0)
                {
                    memoryStream.Write(buffer, 0, size);
                    size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                }
                // 6.组装结束分界线数据体 到内存流中
                memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                // 7.获取二进制数据
                byte[] postBytes = memoryStream.ToArray();
                // 8.HttpWebRequest 组装
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute));

               

                webRequest.Method = "POST";
                webRequest.Timeout = 3000000;
                webRequest.Headers.Add("authorization_token:"+ strcookie);
                webRequest.Headers.Add("sec-ch-ua-mobile: ?0");
                webRequest.Headers.Add("Authorization: Bearer "+ strcookie);
                webRequest.Headers.Add("authorization_key: "+ strkey);

                webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.169.400 QQBrowser/11.0.5130.400";
                webRequest.Headers.Add("device:pc");
                webRequest.Headers.Add("sec-ch-ua-platform: \"Windows\"");
                webRequest.Headers.Add("sec-ch-ua:\"; Not A Brand\";v=\"99\", \"Chromium\";v=\"94\"");
                webRequest.Accept = "*/*";
                webRequest.Headers.Add("Origin: https://register.ccopyright.com.cn");
                
                webRequest.Headers.Add("Sec-Fetch-Site: same-site");
                webRequest.Headers.Add("Sec-Fetch-Mode: cors");
                webRequest.Headers.Add("Sec-Fetch-Dest: empty");
                webRequest.Referer = parameter.Referer;
                webRequest.Headers.Add("Accept-Encoding: gzip, deflate, br");
                webRequest.Headers.Add("Accept-Language: zh-CN,zh;q=0.9");

                webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                webRequest.ContentLength = postBytes.Length;
                if (Regex.IsMatch(parameter.Url, "^https://"))
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                }
                // 9.写入上传请求数据
                using (Stream requestStream = webRequest.GetRequestStream())
                {
                    requestStream.Write(postBytes, 0, postBytes.Length);
                    requestStream.Close();
                }
                // 10.获取响应
                using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), parameter.Encoding))
                    {
                        string body = reader.ReadToEnd();
                        reader.Close();
                        return body;
                    }
                }
            }
        }
        static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }


        public static string HttpGet(HttpParameterType parameter)
        {
            string strcookie = "";
            string strkey = "";
            using (MemoryStream memoryStream = new MemoryStream())
            {
            
            
                // 8.HttpWebRequest 组装
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute));

                if (Static.CcCookies.Count>0)
                {
                    string[] cookieresult = Static.CcCookies[0].Value.ToString().Split('"');
                    strcookie = cookieresult[3];
                    strkey = cookieresult[7];
                }
                else
                {
                    return "未登录";
                }

                webRequest.Method = "GET";
                webRequest.Timeout = 300000;
                webRequest.Headers.Add("authorization_token:" + strcookie);
                webRequest.Headers.Add("sec-ch-ua-mobile: ?0");
                webRequest.Headers.Add("Authorization: Bearer " + strcookie);
                webRequest.Headers.Add("authorization_key: " + strkey);
                webRequest.Accept="application/json, text/plain, */*";
                webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.169.400 QQBrowser/11.0.5130.400";
                webRequest.Headers.Add("device:pc");
                webRequest.Headers.Add("sec-ch-ua-platform: \"Windows\"");
                webRequest.Headers.Add("sec-ch-ua:\"; Not A Brand\";v=\"99\", \"Chromium\";v=\"94\"");                
                webRequest.Headers.Add("Origin: https://register.ccopyright.com.cn");

                webRequest.Headers.Add("Sec-Fetch-Site: same-site");
                webRequest.Headers.Add("Sec-Fetch-Mode: cors");
                webRequest.Headers.Add("Sec-Fetch-Dest: empty");
                webRequest.Referer = "https://register.ccopyright.com.cn/accountReal.html";
                webRequest.Headers.Add("Accept-Encoding: gzip, deflate, br");
                webRequest.Headers.Add("Accept-Language: zh-CN,zh;q=0.9");

                if (Regex.IsMatch(parameter.Url, "^https://"))
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                }

                // 10.获取响应
                using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
                    {
                        string body = reader.ReadToEnd();
                        reader.Close();
                        return body;
                    }
                }
            }
        }


        public static string HttpPost(HttpParameterType parameter)
        {
            string strcookie = "";
            string strkey = "";
            using (MemoryStream memoryStream = new MemoryStream())
            {


                // 8.HttpWebRequest 组装
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute));

                if (Static.CcCookies.Count > 0)
                {
                    string[] cookieresult = Static.CcCookies[0].Value.ToString().Split('"');
                    strcookie = cookieresult[3];
                    strkey = cookieresult[7];
                }
                else
                {
                    return "未登录";
                }

                webRequest.Method = "POST";
                webRequest.Timeout = 300000;
                webRequest.Headers.Add("authorization_token:" + strcookie);
                webRequest.Headers.Add("sec-ch-ua-mobile: ?0");
                webRequest.Headers.Add("Authorization: Bearer " + strcookie);
                webRequest.Headers.Add("authorization_key: " + strkey);

                webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.169.400 QQBrowser/11.0.5130.400";
                webRequest.Headers.Add("device:pc");
                webRequest.Headers.Add("sec-ch-ua-platform: \"Windows\"");
                webRequest.Headers.Add("sec-ch-ua:\"; Not A Brand\";v=\"99\", \"Chromium\";v=\"94\"");
                webRequest.Accept = "*/*";
                webRequest.Headers.Add("Origin: https://register.ccopyright.com.cn");

                webRequest.Headers.Add("Sec-Fetch-Site: same-site");
                webRequest.Headers.Add("Sec-Fetch-Mode: cors");
                webRequest.Headers.Add("Sec-Fetch-Dest: empty");
                webRequest.Referer = parameter.Referer;
                webRequest.Headers.Add("Accept-Encoding: gzip, deflate, br");
                webRequest.Headers.Add("Accept-Language: zh-CN,zh;q=0.9");                
                webRequest.ContentType = "application/json";
                byte[] payload;
                //将Json字符串转化为字节  
                payload = System.Text.Encoding.UTF8.GetBytes(parameter.strJson);
                //设置请求的ContentLength   
                webRequest.ContentLength = payload.Length;

                if (Regex.IsMatch(parameter.Url, "^https://"))
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                }

                // 9.写入上传请求数据
                using (Stream requestStream = webRequest.GetRequestStream())
                {
                    requestStream.Write(payload, 0, payload.Length);
                    requestStream.Close();
                }

                // 10.获取响应
                using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
                    {
                        string body = reader.ReadToEnd();
                        reader.Close();
                        return body;
                    }
                }
            }
        }

        public static byte[] PostCopyrightPaper(string url, WebUserInfo webUserInfo, string referer = null)
        {
            try
            {
                HttpWebRequest httpRequset = (HttpWebRequest)WebRequest.Create(url);
                CookieContainer myCookieContainer = new CookieContainer();
                httpRequset.CookieContainer = myCookieContainer;
                httpRequset.Method = "GET";
                httpRequset.Accept = "application/json, text/plain, */*";
                httpRequset.Host = "oss.ccopyright.com.cn";
                httpRequset.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN,zh;q=0.9");
                httpRequset.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + webUserInfo.authorization_token);
                httpRequset.Headers.Add("authorization_key", webUserInfo.authorization_key);
                httpRequset.Headers.Add("device", "pc");
                httpRequset.Headers.Add("authorization_token", webUserInfo.authorization_token);
                httpRequset.Headers.Add("Origin: https://register.ccopyright.com.cn");
                httpRequset.Headers.Add("sec-ch-ua-platform: Windows");
                httpRequset.Headers.Add("Sec-Fetch-Site: same-site");
                httpRequset.Headers.Add("Sec-Fetch-Mode: cors");
                httpRequset.Headers.Add("Sec-Fetch-Dest: empty");                
                httpRequset.UserAgent = ConfigHelper.GetAppSetting("UserAgent");
                if (referer != null)
                    httpRequset.Referer = referer;
                httpRequset.KeepAlive = true;
                HttpWebResponse request = (HttpWebResponse)httpRequset.GetResponse();//获得 服务端响应                
                Stream responseStream = request.GetResponseStream();
                List<byte> btlst = new List<byte>();
                int b = responseStream.ReadByte();
                while (b > -1)
                {
                    btlst.Add((byte)b);
                    b = responseStream.ReadByte();
                }
                byte[] bts = btlst.ToArray();
                return bts;
               
            }
            catch (Exception ex)
            {
                Log4NetHelper.Error("PostCopyright", url, ex);
                return null;
            }

        }

    }
}
